<?php
/**
 * @author all@cosmos-framework.org
 * @copyright (c) 2013 cosmos-framework.org
 * @license http://www.opensource.org/licenses/mit-license.php
 * @link http://cosmos-framework.org/
 * @package cosmos.framework
 * @version 2.0
 */
namespace Cosmos\Memcache;

use Cosmos\Invoker;
use Cosmos\Memcache;

class Tx extends Invoker {

    /**
     * @param string $methodName
     * @param mixed[] $methodArgs
     * @return mixed
     */
    public function __call($methodName, $methodArgs) {

        $connect = Memcache::connects();

        if (@$connect->getVersion()) {

            if (!$this->_disable()) {

                // is session_id ?
                $s = &$this->componentArgs[1];

                $_[] = $s ? session_id() : '';
                $_[] = $connect->group($this->__a());
                $_[] = $methodName;
                $_[] = $methodArgs;

                $_ = json_encode($_);

                // response expire.
                $s = &$this->componentArgs[0];

                // in response.
                $response = $connect->fetch($_, $s ? : 0);
                if (is_null($response) || $response === false) {
                    try {
                        // invoke response.
                        $response = parent::__call($methodName, $methodArgs);

                        // mapped fill.
                        $connect->set($_, $response, 0, 0);

                    } catch(Exception $e) {

                        // mapped fill.
                        $connect->set($_, false, 0, -1);

                        // fail response.
                        throw $e;
                    }
                }
                // in response.
                return $response;
            }

            // group disable.
            $connect->set($this->__a(), false, 0, -1);
        }

        // invoke response.
        return parent::__call($methodName, $methodArgs);
    }

    /**
     * @access private
     */
    private function _disable() {

        return !strcmp(($_ = &$this->componentArgs[0]), 'disable');
    }

}
